package com.imooc.pan.server.modules.user.controller;

import com.imooc.pan.core.response.R;
import com.imooc.pan.core.utils.IdUtil;
import com.imooc.pan.server.common.annotation.LoginIgnore;
import com.imooc.pan.server.common.utils.UserIdUtil;
import com.imooc.pan.server.modules.user.context.*;
import com.imooc.pan.server.modules.user.converter.UserConverter;
import com.imooc.pan.server.modules.user.po.*;
import com.imooc.pan.server.modules.user.service.RPanUserService;
import com.imooc.pan.server.modules.user.vo.UserInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * @author hhb
 * @data 2024/6/7 16:06
 */
@RestController
@RequestMapping("user")
@Api(tags = "用户模块")
public class UserController {
    @Autowired
    private RPanUserService rPanUserService;

    @Autowired
    private UserConverter userConverter;


    @ApiOperation(
            value = "用户注册接口",
            notes = "该接口提供了用户注册的功能，实现了用户幂等性注册的逻辑",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @LoginIgnore
    @PostMapping("register")
    public R register(@Validated @RequestBody UserRegisterPO userRegisterPO){
        UserRegisterContext userRegisterContext = userConverter.userRegisterPOToUserRegisterContext(userRegisterPO);
        Long userId = rPanUserService.register(userRegisterContext);
        return R.data(IdUtil.encrypt(userId));
    }


    @ApiOperation(
            value = "用户等录接口",
            notes = "该接口提供了用户登录的功能，用户登录后会返回有时效性的accessToken",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @LoginIgnore
    @PostMapping("login")
    public R login(@Validated @RequestBody UserLoginPO userLoginPO){
        UserLoginContext userLoginContext = userConverter.userLoginPOToUserLoginContext(userLoginPO);
        String accessToken = rPanUserService.login(userLoginContext);
        return R.data(accessToken);
    }

    @ApiOperation(
            value = "用户登出接口",
            notes = "该接口提供了用户登出的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @PostMapping("exit")
    public R exit(){
        Long userId = UserIdUtil.get();
        rPanUserService.exit(userId);
        return R.success();
    }


    @ApiOperation(
            value = "用户忘记密码-校验用户名",
            notes = "该接口提供了用户忘记密码-校验用户名的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @LoginIgnore
    @PostMapping("username/check")
    public R checkUserName(@Validated @RequestBody CheckUserNamePO checkUserNamePO){
        CheckUserNameContext checkUserNameContext = userConverter.checkUserNamePOTOCheckUserNameContext(checkUserNamePO);
        String question = rPanUserService.checkUserName(checkUserNameContext);
        return R.data(question);
    }

    @ApiOperation(
            value = "用户忘记密码-校验密保答案",
            notes = "该接口提供了用户忘记密码-校验密保答案的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @LoginIgnore
    @PostMapping("answer/check")
    public R checkUserName(@Validated @RequestBody CheckAnswerPO checkAnswerPO){
        CheckAnswerContext checkAnswerContext = userConverter.checkAnswerPOToCheckAnswerContext(checkAnswerPO);
        String token = rPanUserService.checkAnswer(checkAnswerContext);
        return R.data(token);
    }

    @ApiOperation(
            value = "用户忘记密码-修改密码",
            notes = "该接口提供了用户忘记密码-修改密码的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @LoginIgnore
    @PostMapping("password/reset")
    public R resetPassword(@Validated @RequestBody ResetPasswordPo resetPasswordPo){
        ResetPasswordContext resetPasswordContext = userConverter.resetPasswordPoToResetPasswordContext(resetPasswordPo);
        rPanUserService.resetPassword(resetPasswordContext);
        return R.success();
    }


    @ApiOperation(
            value = "用户修改密码",
            notes = "该接口提供了用户修改密码的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @PostMapping("password/change")
    public R changePassword(@Validated @RequestBody ChangePasswordPO changePasswordPO){
        ChangePasswordContext changePasswordContext = userConverter.changePasswordPOToChangePasswordContext(changePasswordPO);
        changePasswordContext.setUserId(UserIdUtil.get());
        rPanUserService.changePassword(changePasswordContext);
        return R.success();
    }

    @ApiOperation(
            value = "查询用户基本信息",
            notes = "该接口提供了查询用户基本信息的功能",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @GetMapping("/")
    public R<UserInfoVo> info(){
        UserInfoVo userInfoVo = rPanUserService.info(UserIdUtil.get());
        return R.data(userInfoVo);
    }
}
